/**
 * 高阶函数：
 *    一个函数的入参或返回值是函数类型的话，那么它就是一个高阶函数
 *      forEach
 *      map
 *      reduce
 *      filter
 *      ...
 *
 * 高阶组件：
 *    本质上是一个函数【高阶函数】
 *    接受一个组件做为参数，返回一个新组件
 *
 */

import React, { useImperativeHandle } from "react";

/**
 * React.forwardRef Refs 转发
 *    接受一个带有 props 与 ref 两个参数的一个 render 函数
 *        props
 *          传递给组件的 Props
 *        ref
 *          传递给组件的 ref 内容
 *
 *    返回值，就是一个组件
 */
const Hello = React.forwardRef((props, ref) => {
  console.log("props", props);
  console.log("ref", ref);

  /**
   * 作用：
   *    让组件标记该组件时，获取到的内容为什么，就是对外的暴露
   */
  useImperativeHandle(ref, () => ({
    a: 1,
    b: 2,
  }));

  return (
    <div>
      <h2>Hello</h2>
      <p>我的一个皮</p>
    </div>
  );
});

export default class App extends React.Component {
  // 创建 ref 对象, 返回值为一个带有 current 属性的对象
  //    类型参数T,用于描述后续标记的元素类型，后边后续代码提示
  h1Ref = React.createRef<HTMLHeadingElement>();
  helloRef = React.createRef<Hello>();

  fn1() {
    console.log(this.h1Ref.current);
  }

  fn2() {
    console.log(this.helloRef.current);
  }

  render() {
    return (
      <div>
        <h1 ref={this.h1Ref}>哈喽 ref</h1>
        <Hello ref={this.helloRef} name="张三" age="18" />
        <hr />
        <button onClick={() => this.fn1()}>点我1</button>
        <button onClick={() => this.fn2()}>点我2</button>
      </div>
    );
  }
}
